package com.yunkeji.common.msg;

import cn.craccd.mongoHelper.utils.MongoHelper;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yunkeji.common.constant.SysIdConstant;
import com.yunkeji.common.enums.app.MsgTypeEnums;
import com.yunkeji.common.msg.bo.HttpResp;
import com.yunkeji.common.msg.bo.KmsgDataReq;
import com.yunkeji.common.msg.bo.RollingMsg;
import com.yunkeji.common.msg.consts.MsgConstant;
import com.yunkeji.common.msg.utils.MsgHttpUtils;
import com.yunkeji.common.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;

@Slf4j
public class Push {
    public static String BASE_HOST = "http://localhost";

    public static void init(String env) {
        BASE_HOST = env;
    }

    /** HTTP请求线程池 */
    private static Executor HTTP_EXECUTOR = SpringUtil.getBean("httpExecutor", Executor.class);
    /** monggo工具 */
    private static final MongoHelper HELPER = SpringUtil.getBean(MongoHelper.class);

    /**
     * 发送单条消息
     *
     * @param from
     * @param to
     * @param type
     * @param receipt
     * @param msg
     * @param offline
     */
    protected static boolean sendSingleMsg(
            Long from, List<Long> to, Integer type, Integer receipt, String msg, int offline) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", from);
        datas.set("to", to);
        datas.set("type", type);
        datas.set("receipt", receipt);
        datas.set("offline", offline);
        datas.set("msg", JSONUtil.createObj().set("content", msg));
        HttpResp httpResp =
                MsgHttpUtils.sendNormalPostHttp(BASE_HOST + MsgConstant.URL_普通消息, datas);
        return httpResp.isOk() && httpResp.getJsonData().getInt("code") == 0;
    }

    /**
     * 推送通话信令-单个
     *
     * @param from
     * @param to
     */
    protected static boolean pushCallSignalSingle(
            Long from, Long to, JSONObject content, MsgTypeEnums msgTypeEnums) {
        return pushCallSignalBatch(from, ListUtil.of(to), content, msgTypeEnums);
    }

    /**
     * 推送通话信令-批量
     *
     * @param from
     * @param to
     */
    protected static boolean pushCallSignalBatch(
            Long from, List<Long> to, JSONObject content, MsgTypeEnums msgTypeEnums) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", from);
        datas.set("to", to);
        datas.set("type", msgTypeEnums.getCode());
        datas.set("receipt", MsgConstant.NO);
        datas.set("offline", MsgConstant.NO);
        datas.set("msg", content);
        HTTP_EXECUTOR.execute(() -> send(BASE_HOST + MsgConstant.URL_普通消息, datas));
        return true;
    }
    /**
     * 发送收条消息-单条
     *
     * @param from
     * @param to
     */
    protected static boolean sendReceiptSingle(Long from, Long to, JSONObject param) {
        return sendReceiptBatch(from, ListUtil.of(to), param);
    }

    /**
     * 发送收条消息-批量
     *
     * @param from
     * @param to
     */
    protected static boolean sendReceiptBatch(Long from, List<Long> to, JSONObject param) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", from);
        datas.set("to", to);
        datas.set("type", MsgTypeEnums.消息收条.getCode());
        datas.set("offline", MsgConstant.YES);
        datas.set("receipt", MsgConstant.YES);
        datas.set("msg", param);
        log.info("sendReceiptBatch:{}", datas.toStringPretty());
        return send(BASE_HOST + MsgConstant.URL_普通消息, datas);
    }

    /**
     * 发送跑马灯消息
     *
     * @param to
     */
    protected static boolean sendRollingMsg(List<Long> to, RollingMsg rollingMsg) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", SysIdConstant.系统);
        datas.set("to", to);
        datas.set("type", MsgTypeEnums.跑马灯消息.getCode());
        datas.set("receipt", MsgConstant.NO);
        datas.set("offline", MsgConstant.YES);
        datas.set("msg", rollingMsg);
        return send(BASE_HOST + MsgConstant.URL_普通消息, datas);
    }

    /**
     * 发送链接消息
     *
     * @param to
     */
    protected static boolean sendLinkMsg(List<Long> to, String content, String scheme) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", SysIdConstant.系统);
        datas.set("to", to);
        datas.set("type", MsgTypeEnums.链接消息.getCode());
        datas.set("receipt", MsgConstant.NO);
        datas.set("offline", MsgConstant.YES);
        datas.set("msg", JSONUtil.createObj().set("content", content).set("scheme", scheme));
        return send(BASE_HOST + MsgConstant.URL_普通消息, datas);
    }

    /**
     * 发送普通文本消息-单条
     *
     * @param from
     * @param to
     */
    protected static boolean sendTextSingle(Long from, Long to, String content) {
        return sendTextBatch(from, ListUtil.of(to), JSONUtil.createObj().set("content", content));
    }
    /**
     * 发送普通文本消息-批量
     *
     * @param from
     * @param to
     */
    protected static boolean sendTextBatch(Long from, List<Long> to, JSONObject content) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("from", from);
        datas.set("to", to);
        datas.set("type", MsgTypeEnums.文字消息.getCode());
        datas.set("receipt", MsgConstant.NO);
        datas.set("offline", MsgConstant.YES);
        datas.set("msg", content);
        HttpServletRequest request = ServletUtils.getRequest();
        datas.set("branch", request.getHeader("branch"));
        datas.set("serial", request.getHeader("serial"));
        return send(BASE_HOST + MsgConstant.URL_普通消息, datas);
    }

    /**
     * 发送
     *
     * @param url
     * @param param
     * @return
     */
    private static boolean send(String url, JSONObject param, Boolean needSave) {
        if (needSave) {
            // 存日志
            Date date = new Date();
            String dateStr = DateUtil.format(date, DatePattern.SIMPLE_MONTH_PATTERN);
            param.set("createTime", new Date().getTime());
            HELPER.getMongoTemplate().insert(param, "ykj_msg_" + dateStr);
        }
        HttpResp httpResp = MsgHttpUtils.sendNormalPostHttp(url, param);
        return httpResp.isOk() && httpResp.getJsonData().getInt("code") == 0;
    }

    /**
     * 发送
     *
     * @param url
     * @param param
     * @return
     */
    private static boolean send(String url, JSONObject param) {
        return send(url, param, true);
    }

    /**
     * 刷新Kmsg的Token
     *
     * @return
     */
    protected static String refreshKmsgToken(Long platformId) {
        KmsgDataReq build = KmsgDataReq.builder().userId(platformId).build();
        HttpResp httpResp =
                MsgHttpUtils.sendNormalPostHttp(
                        BASE_HOST + MsgConstant.URL_获取消息系统TOKEN, JSONUtil.parseObj(build));
        if (httpResp.isOk() && httpResp.getJsonData().getInt("code") == 0) {
            return httpResp.getJsonData().getJSONObject("data").getStr("token");
        } else {
            return "";
        }
    }

    /**
     * 用户到客服
     *
     * @return
     */
    protected static boolean userToService(Long from, JSONObject content) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("userId", from);
        datas.set("type", MsgTypeEnums.文字消息.getCode());
        datas.set("data", content);
        return send(BASE_HOST + MsgConstant.URL_用户给客服发消息, datas);
    }
    /**
     * 客服到用户
     *
     * @return
     */
    protected static boolean serviceToUser(Long from, Long to, JSONObject content) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("kefuId", from);
        datas.set("userId", to);
        datas.set("type", MsgTypeEnums.文字消息.getCode());
        datas.set("data", content);
        return send(BASE_HOST + MsgConstant.URL_客服给用户发消息, datas);
    }

    /**
     * 发送验证码
     *
     * @return
     */
    public static void sendSMSCode(String phoneNum, String code, String plat) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("phone", phoneNum);
        datas.set("smsCode", code);
        datas.set("plat", plat);
        send(BASE_HOST + MsgConstant.URL_验证码, datas, false);
    }
    /**
     * 踢下线
     *
     * @return
     */
    public static void kickout(Long platformId, String reason) {
        JSONObject datas = JSONUtil.createObj();
        datas.set("userId", platformId);
        datas.set("reason", reason);
        send(BASE_HOST + MsgConstant.URL_踢下线, datas, false);
    }
}
